package com.illtamer.infinite.derive.configuration.config;

import com.illtamer.infinite.derive.Resource;
import com.illtamer.infinite.derive.path.FilePath;
import com.illtamer.infinite.derive.util.Assert;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.*;
import java.net.URL;
import java.net.URLConnection;

/**
 * You can extend this class instead of implements {@link ConfigurableStarter}
 * */
public class ConfigurationStarter implements ConfigurableStarter {

    private final FilePath rootDataFolder;

    public ConfigurationStarter() {
        this(new File("config"));
    }

    public ConfigurationStarter(File dataFolder) {
        if (!dataFolder.exists()) dataFolder.mkdirs();
        this.rootDataFolder = (FilePath) Resource.instance().root(dataFolder);
    }

    @Override
    public File getDataFolder() {
        return rootDataFolder.getFile();
    }

    /**
     * Save the file from application-cache to file-system
     * */
    @Override
    public void saveResource(@NotNull String relativePath, boolean replace) {
        InputStream input = getResource(relativePath);
        Assert.notNull(input, "File %s can not be found in %s", relativePath, rootDataFolder.getFile());

        File outFile = new File(rootDataFolder.getFile(), relativePath);
        int lastIndex = relativePath.lastIndexOf(47);
        File outDir = new File(rootDataFolder.getFile(), relativePath.substring(0, Math.max(lastIndex, 0)));
        if (!outDir.exists())
            outDir.mkdirs();

        if (outFile.exists() && !replace) {
            System.out.println("Could not save " + outFile.getName() + " to " + outFile + " because " + outFile.getName() + " already exists.");
        } else {
            try (
                    OutputStream out = new FileOutputStream(outFile)
            ) {
                byte[] buf = new byte[1024];
                int len;
                while((len = input.read(buf)) > 0)
                    out.write(buf, 0, len);
                input.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Nullable
    public InputStream getResource(@NotNull String filename) {
        try {
            URL url = this.getClass().getClassLoader().getResource(filename);
            if (url == null) {
                return null;
            } else {
                URLConnection connection = url.openConnection();
                connection.setUseCaches(false);
                return connection.getInputStream();
            }
        } catch (IOException var4) {
            return null;
        }
    }

}
